//
//  Geometry.m
//  V3d_Cocoa
//
//  Created by Y my on 11-4-23.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "Geometry.h"


@implementation Matrix4
@synthesize _00, _01, _02, _03;
@synthesize _10, _11, _12, _13;
@synthesize _20, _21, _22, _23;
@synthesize _30, _31, _32, _33;

- (id)initWithMatrix4:(Matrix4*)mat
{
	self = [super init];
	if (self)
	{
		_00 = mat._00; _01 = mat._01; _02 = mat._02; _03 = mat._03;
		_10 = mat._10; _11 = mat._11; _12 = mat._12; _13 = mat._13;
		_20 = mat._20; _21 = mat._21; _22 = mat._22; _23 = mat._23;
		_30 = mat._30; _31 = mat._31; _32 = mat._32; _33 = mat._33;
	}
	return self;
}

- (id)init
{
	self = [super init];
	if (self)
	{
		_00 = 1.0f; _01 = 0.0f; _02 = 0.0f; _03 = 0.0f;
		_10 = 0.0f; _11 = 1.0f; _12 = 0.0f; _13 = 0.0f;
		_20 = 0.0f; _21 = 0.0f; _22 = 1.0f; _23 = 0.0f;
		_30 = 0.0f; _31 = 0.0f; _32 = 0.0f; _33 = 1.0f;
	}
	return self;
}

- (void)clear
{
	_00 = 1.0f; _01 = 0.0f; _02 = 0.0f; _03 = 0.0f;
	_10 = 0.0f; _11 = 1.0f; _12 = 0.0f; _13 = 0.0f;
	_20 = 0.0f; _21 = 0.0f; _22 = 1.0f; _23 = 0.0f;
	_30 = 0.0f; _31 = 0.0f; _32 = 0.0f; _33 = 1.0f;
}

- (void)multiple:(Matrix4*)mat
{
	Matrix4* res = [[[Matrix4 alloc] init] autorelease];
	
	res._00 = _00*mat._00 + _01*mat._10 + _02*mat._20 + _03*mat._30;
	res._01 = _00*mat._01 + _01*mat._11 + _02*mat._21 + _03*mat._31;
	res._02 = _00*mat._02 + _01*mat._12 + _02*mat._22 + _03*mat._32;
	res._03 = _00*mat._03 + _01*mat._13 + _02*mat._23 + _03*mat._33;
	
	res._10 = _10*mat._00 + _11*mat._10 + _12*mat._20 + _13*mat._30;
	res._11 = _10*mat._01 + _11*mat._11 + _12*mat._21 + _13*mat._31;
	res._12 = _10*mat._02 + _11*mat._12 + _12*mat._22 + _13*mat._32;
	res._13 = _10*mat._03 + _11*mat._13 + _12*mat._23 + _13*mat._33;
	
	res._20 = _20*mat._00 + _21*mat._10 + _22*mat._20 + _23*mat._30;
	res._21 = _20*mat._01 + _21*mat._11 + _22*mat._21 + _23*mat._31;
	res._22 = _20*mat._02 + _21*mat._12 + _22*mat._22 + _23*mat._32;
	res._23 = _20*mat._03 + _21*mat._13 + _22*mat._23 + _23*mat._33;
	
	res._30 = _30*mat._00 + _31*mat._10 + _32*mat._20 + _33*mat._30;
	res._31 = _30*mat._01 + _31*mat._11 + _32*mat._21 + _33*mat._31;
	res._32 = _30*mat._02 + _31*mat._12 + _32*mat._22 + _33*mat._32;
	res._33 = _30*mat._03 + _31*mat._13 + _32*mat._23 + _33*mat._33;
	
	_00 = res._00;
	_01 = res._01;
	_02 = res._02;
	_03 = res._03;
	
	_10 = res._10;
	_11 = res._11;
	_12 = res._12;
	_13 = res._13;
	
	_20 = res._20;
	_21 = res._21;
	_22 = res._22;
	_23 = res._23;
	
	_30 = res._30;
	_31 = res._31;
	_32 = res._32;
	_33 = res._33;
}

- (void)normalize
{
	if (_33 != 0 && _33 != 1)
	{
		_00 /= _33;
		_01 /= _33;
		_02 /= _33;
		_03 /= _33;
		
		_10 /= _33;
		_11 /= _33;
		_12 /= _33;
		_13 /= _33;
		
		_20 /= _33;
		_21 /= _33;
		_22 /= _33;
		_23 /= _33;
		
		_30 /= _33;
		_31 /= _33;
		_32 /= _33;
		_33 = 1;	
	}
}
@end



@implementation Point3D
@synthesize x, y, z, w;

- (id)init
{
	self = [super init];
	if (self != nil)
	{
		x = y = z = 0;
		w = 1;
	}
	return self;
}

- (id)initWithX:(float)xx Y:(float)yy Z:(float)zz
{
	self = [super init];
	if (self != nil)
	{
		x = xx;
		y = yy;
		z = zz;
		w = 1;
	}
	return self;
}

- (void)clear
{
	x = y = z = 0;
	w = 1;
}

- (void)multiple:(Matrix4*)mat
{
	Point3D* res = [[[Point3D alloc] init] autorelease];
	res.x = x*mat._00 + y*mat._10 + z*mat._20 + w*mat._30;
	res.y = x*mat._01 + y*mat._11 + z*mat._21 + w*mat._31;
	res.z = x*mat._02 + y*mat._12 + z*mat._22 + w*mat._32;
	res.w = x*mat._03 + y*mat._13 + z*mat._23 + w*mat._33;

	x = res.x;
	y = res.y;
	z = res.z;
	w = res.w;
}

- (void)normalize
{
	if (w != 0 && w != 1)
	{
		x /= w;
		y /= w;
		z /= w;
		w = 1;
	}
	
}
@end